/** @file
  This is a test application that demonstrates how to use the C-style entry point
  for a shell application.

  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Library/HiiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiHiiServicesLib.h>

#include "MyFontGlyph.c"

EFI_HII_HANDLE  mHiiHandle;
EFI_GUID        mFontPackageListGuid = {0x2b3d10b4, 0xa6c5, 0x49b7, {0xbc, 0x2f, 0xf3, 0x89, 0x32, 0xd2, 0xbe, 0xee}};
EFI_GUID        mStrPackageListGuid = {0xa15a43ed, 0x3a25, 0x46bf, {0xab, 0x5f, 0x06, 0xab, 0xac, 0x89, 0x72, 0x6d}};

#pragma warning ( disable : 4819 )

/**
  UEFI application entry point which has an interface similar to a
  standard C main function.

  The ShellCEntryLib library instance wrappers the actual UEFI application
  entry point and calls this ShellAppMain function.

  @param[in] Argc     The number of items in Argv.
  @param[in] Argv     Array of pointers to strings.

  @retval  0               The application exited normally.
  @retval  Other           An error occurred.

**/
INTN
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  UINTN  Index;
  if (Argc == 1) {
    Print (L"Argv[1] = NULL\n");
  }
  for (Index = 1; Index < Argc; Index++) {
    Print(L"Argv[%d]: \"%s\"\n", Index, Argv[Index]);
  }

  EFI_HII_SIMPLE_FONT_PACKAGE_HDR *SimplifiedFont;
  UINT32 PackageLength;
  UINT8 *Package;
  UINT8 *Location;

  EFI_HII_HANDLE *HiiHandlerBuffer;

  // 注意这个返回是数组，而且需要释放内存FreePool()
  HiiHandlerBuffer = HiiGetHiiHandles(&mFontPackageListGuid);
  if (HiiHandlerBuffer == NULL)
  {

    //
    // Add 4 bytes to the header for entire length for HiiAddPackages use only.
    //
    //    +--------------------------------+ <-- Package
    //    |                                |
    //    |    PackageLength(4 bytes)      |
    //    |                                |
    //    |--------------------------------| <-- SimplifiedFont
    //    |                                |
    //    |EFI_HII_SIMPLE_FONT_PACKAGE_HDR |
    //    |                                |
    //    |--------------------------------| <-- Location
    //    |                                |
    //    |     gUsStdNarrowGlyphData      |
    //    |                                |
    //    +--------------------------------+

    // PackageLength = sizeof(EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + nMyNarrowGlyphSize + nMyWideGlyphSize + 4;
    PackageLength = sizeof(EFI_HII_SIMPLE_FONT_PACKAGE_HDR) + nMyWideGlyphSize + 4;
    Package = AllocateZeroPool(PackageLength);
    ASSERT(Package != NULL);

    WriteUnaligned32((UINT32 *)Package, PackageLength);
    SimplifiedFont = (EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)(Package + 4);
    SimplifiedFont->Header.Length = (UINT32)(PackageLength - 4);
    SimplifiedFont->Header.Type = EFI_HII_PACKAGE_SIMPLE_FONTS;
    // SimplifiedFont->NumberOfNarrowGlyphs = (UINT16)(nMyNarrowGlyphSize / sizeof(EFI_NARROW_GLYPH));
    SimplifiedFont->NumberOfWideGlyphs = (UINT16)(nMyWideGlyphSize / sizeof(EFI_NARROW_GLYPH));

    Location = (UINT8 *)(&SimplifiedFont->NumberOfWideGlyphs + 1);
    // CopyMem(Location, gMyNarrowGlyphData, nMyNarrowGlyphSize);
    // Location += nMyNarrowGlyphSize;
    CopyMem(Location, gMyWideGlyphData, nMyWideGlyphSize);

    //
    // Add this simplified font package to a package list then install it.
    //
    mHiiHandle = HiiAddPackages(
        &mFontPackageListGuid,
        NULL,
        Package,
        NULL);
    ASSERT(mHiiHandle != NULL);
    FreePool(Package);
  }
  else
  {
    FreePool(HiiHandlerBuffer);
  }

  Print(L"Hello,World!\n");
  Print(L"你好,世界!\n");
  Print(L"Hello,UEFI!\n");
  Print(L"你好,UEFI!\n");
  Print(L"Hello,汉字!\n");

  Print(L"\n");

  // 打印过长会异常
  Print(L"根据2025年3月30日的新闻报道，以下是近期值得关注的国际大事：\n");
  Print(L"\n");
  Print(L"1. 日本福岛核污染水排海争议\n");
  Print(L"\n");
  Print(L"2. 缅甸强震及国际援助\n");
  Print(L"\n");
  Print(L"3. 美国在菲律宾的军事部署\n");
  Print(L"\n");
  Print(L"4. 乌克兰与美国的矿产协议\n");
  Print(L"\n");
  Print(L"5. 欧盟战略技术投资\n");
  Print(L"\n");
  Print(L"6. 中巴经贸合作深化\n");
  Print(L"\n");
  Print(L"7. 其他国际动态\n");
  Print(L"\n");

  Print(L"\n");

  // 注意这个返回是数组，而且需要释放内存FreePool()
  HiiHandlerBuffer = HiiGetHiiHandles(&mStrPackageListGuid);
  if (HiiHandlerBuffer == NULL)
  {
    mHiiHandle = HiiAddPackages(
        &mStrPackageListGuid,
        NULL,
        HiiCHSStrings,
        NULL);
  }
  else
  {
    mHiiHandle = HiiHandlerBuffer[0];
    FreePool(HiiHandlerBuffer);
  }

  Print(L"Supported Languages: %a\n", HiiGetSupportedLanguages(mHiiHandle));

  Print(HiiGetString(mHiiHandle, STRING_TOKEN(STR_HELLO_WORLD), NULL));
  Print(HiiGetString(mHiiHandle, STRING_TOKEN(STR_HELLO_WORLD), "zh-Hans"));
  Print(L"\n");

  Print(HiiGetPackageString(&mStrPackageListGuid, STRING_TOKEN(STR_HELLO_WORLD), NULL));
  Print(HiiGetPackageString(&mStrPackageListGuid, STRING_TOKEN(STR_HELLO_WORLD), "zh-Hans"));
  Print(L"\n");

  // HiiRemovePackages(mHiiHandle);

  return 0;
}
